from abc import ABC, abstractmethod
import io
import json
import tool.config.config as cfg
import vosk

# recognizer = vosk.KaldiRecognizer(model, 16000)
# recognizer.SetWords(True)
from funasr import AutoModel
# 注意：funasr 1.2.7版本中AutoModel没有list_available_models方法
# 由于本地模型目录不存在，暂时不初始化funasr_model
# config = cfg.get_config("sys.toml")
# local_model_path=config['AUDIO']['FUNASR_MODEL_PATH']
# funasr_model = AutoModel(disable_update=True,model="iic/speech_paraformer-large-vad-punc_asr_nat-zh-cn-16k-common-vocab8404-pytorch",
#                         model_path=local_model_path)

class SpeechRcognitionModel(ABC):
    @abstractmethod
    def speech_recognition(self,audio_file):
        pass
class FunasrSpeechRcognitionModel(SpeechRcognitionModel):
    def speech_recognition(self,audio_file):
        from funasr import AutoModel
        config = cfg.get_config("config.toml")
        try:
            model = AutoModel(disable_update=True,model=local_model_path)
            res = model.generate(input=audio_file)
            return res[0]['text']
        except Exception as e:
            print(f"音频识别失败: {e}")

class VoskSpeechRcognitionModel():
    def __init__(self):
        super().__init__()
        model = vosk.Model("D:\\myproject\\git\\s_he\\s-he\\model\\vosk-model-cn-0.22")  # 模型路径
        if not model:
            raise ValueError("Vosk model not found. Please check the model path.")
        self.recognizer = vosk.KaldiRecognizer(model, 16000)
    def accept_wave(self, audio_file):
        try:
            audio_stream = io.BytesIO(audio_file)
            # 分块处理音频以提高效率
            while True:
                chunk = audio_stream.read(4096)
                if not chunk:
                    break
                self.recognizer.AcceptWaveform(chunk)
        except Exception as e:
            print(f"音频识别失败: {e}")

    def get_results(self):
        results = json.loads(self.recognizer.FinalResult()).get("text")
        self.recognizer.Reset()
        return results if results else None
    
class TencentCloudRcognition(SpeechRcognitionModel):
    def speech_recognition(self,audio_file):
        import base64
        import hashlib
        import hmac
        import time
        import json
        import requests
        config = cfg.get_config("sys.toml")
        service = "asr"
        action = "SentenceRecognition"
        version = "2019-06-14"
        region = "ap-chengdu"
        timestamp = int(time.time())
        host = "asr.tencentcloudapi.com"
        # 音频格式自动检测（根据实际格式修改）
        audio_format = "wav"  # 支持 wav, mp3, m4a, flac, aac, amr, 3gp 等
        SECRET_ID=config["AUDIO"]["SECRET_ID"]
        SECRET_KEY=config["AUDIO"]["SECRET_KEY"]
        payload = {
            "ProjectId": 0,
            "SubServiceType": 2,
            "EngSerViceType": "16k_zh",
            "SourceType": 1,  # 关键：1 表示直接上传二进制数据
            "VoiceFormat": audio_format,
            "UsrAudioKey": "audio_" + str(timestamp),  # 唯一标识
            "Data": base64.b64encode(audio_file).decode('utf-8'),  # 二进制转Base64
            "DataLen": len(audio_file)  # 原始数据长度
        }

        # 3. 生成签名（包含host和content-type）
        canonical_headers = f"content-type:application/json; charset=utf-8\nhost:{host}\n"
        signed_headers = "content-type;host"
        hashed_payload = hashlib.sha256(json.dumps(payload).encode('utf-8')).hexdigest()

        canonical_request = f"POST\n/\n\n{canonical_headers}\n{signed_headers}\n{hashed_payload}"
        date = time.strftime("%Y-%m-%d", time.gmtime(timestamp))
        credential_scope = f"{date}/{service}/tc3_request"
        hashed_canonical_request = hashlib.sha256(canonical_request.encode('utf-8')).hexdigest()
        string_to_sign = f"TC3-HMAC-SHA256\n{timestamp}\n{credential_scope}\n{hashed_canonical_request}"

        # 计算签名
        def sign(key, msg):
            return hmac.new(key, msg.encode("utf-8"), hashlib.sha256).digest()

        secret_date = sign(("TC3" + SECRET_KEY).encode("utf-8"), date)
        secret_service = sign(secret_date, service)
        secret_signing = sign(secret_service, "tc3_request")
        signature = hmac.new(secret_signing, string_to_sign.encode("utf-8"), hashlib.sha256).hexdigest()

        # 4. 构造请求
        url = f"https://{host}/"
        headers = {
            "Authorization": f"TC3-HMAC-SHA256 Credential={SECRET_ID}/{credential_scope}, "
                            f"SignedHeaders={signed_headers}, Signature={signature}",
            "Content-Type": "application/json; charset=utf-8",
            "X-TC-Action": action,
            "X-TC-Timestamp": str(timestamp),
            "X-TC-Version": version,
            "X-TC-Region": region,
            "Host": host
        }

        # 5. 发送请求
        try:
            response = requests.post(url, headers=headers, json=payload)
            result = response.json()
            print(f"🎤 识别结果: {result}")
            return result['Response']['Result']
            
        except Exception as e:
            print(f"⚠️ 请求异常: {str(e)}")
